package org.broncho.ccs;

import static org.broncho.ccs.Task.CCSLOG_PROPERTIES;
import static org.broncho.ccs.Task.MOD_VALUE;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.Scanner;

/**
 * 自动化执行流程
 * 
 * @author ZhangXiao
 * @time 2013年9月1日
 */
public class Execute {

	private static final String INFORMATION_LOG = "Record Current Execute Status\n#EDGE: N*N The EDGE Equals N\n#START: The Strategy SID START Number\n#END: The Strategy SID END Number \n#Notice: The END SID Not included In Execute Range, STAET < END <= Math.pow(2,edge)\n#STEP: The STEP For START Increase";

	private static final String INFORMATION_IN = "Come In CCS Compute System ...";

	private static final String INFORMATION_EXIT = "Quit CCS Compute System ...";

	private static final String INFORMATION_PROMPT = "Key Down Any Key Continue, but 'q' or 'quit' Will Quit...";

	private static Properties p;

	private static File log = new File(System.getProperty("user.dir")
			+ File.separator + CCSLOG_PROPERTIES);

	private static int edge;

	private static int start;

	private static int end;

	private static int step;

	/**
	 * 加载外部属性文件
	 */
	private static void loadProperties() {
		p = new Properties();
		if (!log.exists()) {
			try {
				throw new Exception(CCSLOG_PROPERTIES + " Not exists");
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				System.exit(0);
			}
		}
		try {
			p.load(new FileInputStream(log));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			System.out.println(e.getMessage());
			System.out.println("Load " + CCSLOG_PROPERTIES + " File Failed...");
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println(e.getMessage());
			System.out.println("Load " + CCSLOG_PROPERTIES + " File Failed...");
		}
	}

	/**
	 * 存储信息到属性文件
	 */
	private static void storeProperties() {
		FileOutputStream fout = null;
		try {
			fout = new FileOutputStream(log);
			p.store(fout, INFORMATION_LOG);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (fout != null) {
				try {
					fout.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 读取属性文件的值到变量
	 */
	private static void loadValue() {
		edge = Integer.parseInt(p.getProperty("EDGE"));
		start = Integer.parseInt(p.getProperty("START"));
		end = p.getProperty("END") == null || p.getProperty("END").equals("") ? (int) Math
				.pow(2, edge) : Integer.parseInt(p.getProperty("END"));
		step = Integer.parseInt(p.getProperty("STEP"));
	}

	/**
	 * 更新变量的值
	 */
	private static void updateValue() {
		int max = (int) Math.pow(MOD_VALUE, edge);
		if (end >= max) {
			edge++;
			start = 0;
			end = step;
		} else {
			start = end;
			end = end + step;
			end = (end > max) ? max : end;
		}
	}

	/**
	 * 设置属性的值
	 * 
	 * @param edge
	 *            边
	 * @param start
	 *            启动参数，正整数
	 * @param end
	 *            启动参数，正整数 <strong>start<end<(int)Math.pow(2,edge)
	 *            {@link java.lang.Math#pow(double, double)}<strong>
	 * @param step
	 *            参数增长步长
	 */
	private static void setProperties(int edge, int start, int end, int step) {
		p.setProperty("EDGE", edge + "");
		p.setProperty("START", start + "");
		p.setProperty("END", end + "");
		p.setProperty("STEP", step + "");
	}

	/**
	 * 计算系统执行流程
	 */
	public static void execute() {
		Scanner scan = new Scanner(System.in);
		System.out.println(INFORMATION_IN);
		String get = "";
		do {
			Execute.loadProperties();
			Execute.loadValue();
			Task task = new Task(Execute.edge, Execute.start, Execute.end,
					System.getProperty("user.name"));
			new Compute(task).runTask();
			Execute.updateValue();
			Execute.setProperties(Execute.edge, Execute.start, Execute.end,
					Execute.step);
			Execute.storeProperties();
			System.out.println(INFORMATION_PROMPT);
			get = scan.nextLine();
		} while (!(get.toLowerCase().equals("quit") || get.toLowerCase()
				.equals("q")));
		scan.close();
		System.out.println(INFORMATION_EXIT);
	}

}
